package be.kdg.bombermanunlimited.client.gui.startup;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import be.kdg.bombermanunlimited.client.gui.layout.VerticalFlowLayout;
import be.kdg.bombermanunlimited.client.gui.listener.WindowFlowListener;

public class ClientSettings extends JPanel {

	private static final long serialVersionUID = 1L;

	/**
	 * window componenten
	 */
	private JSpinner sRingPort;
	private JLabel lRingPort;

	private JTextField tfHostAddress;
	private JLabel lHostAddress;
	private JSpinner sHostPort;
	private JLabel lHostPort;

	private JTextField tfUsername;
	private JLabel lUsername;
	private JLabel lMusicPath;
	private JTextField tfMusicPath;
	private JButton bBrowse;

	private JButton connect;

	private JLabel status;

	private WindowFlowListener wfl;

	/**
	 * maak een client settings panel aan
	 * @param listener de luisteraar die moet weten of het volgende scherm geladen mag worden
	 */
	public ClientSettings(WindowFlowListener listener) {
		super(new VerticalFlowLayout());
		wfl = listener;
		FormListener fl = new FormListener();

		// connect is een classe die AbstractAction extends
		connect = new JButton(new Connect("Connect", this));
		status = new JLabel("Fill in all fields!");

		// standaard kan je nog niet connecten, je moet eerst alles invullen
		connect.setEnabled(false);

		// een klein subpanel met een border
		JPanel subPanel = new JPanel();
		subPanel.setLayout(new VerticalFlowLayout());
		subPanel.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Client settings"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		// voeg een subpanel toe voor de internet settings
		subPanel.add(createInternetSettings());
		// subpanel voor user ettings
		subPanel.add(createUserSettings());
		// connect knop
		subPanel.add(connect);

		// voeg het subpanel toe
		add(subPanel);
		// voeg een status label toe, hierin zal de huidige status staan
		add(status);

		// stel de minimum, maximum en standaard waardes in voor de poorten
		SpinnerNumberModel snm = (SpinnerNumberModel) sHostPort.getModel();
		snm.setMinimum(0);
		snm.setMaximum(65535);
		snm.setValue(2020);

		snm = (SpinnerNumberModel) sRingPort.getModel();
		snm.setMinimum(0);
		snm.setMaximum(65535);
		snm.setValue(2000);

		// voeg luisteraars toe zodat de connect knop eventueel ge-enabled kan worden.
		tfHostAddress.getDocument().addDocumentListener(fl);
		sHostPort.getModel().addChangeListener(fl);
		sRingPort.getModel().addChangeListener(fl);
		tfUsername.getDocument().addDocumentListener(fl);
	}

	private JPanel createInternetSettings() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();

		panel.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Internet settings"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		lRingPort = new JLabel("Local port: ");
		sRingPort = new JSpinner();
		sRingPort.setPreferredSize(new Dimension(100, sRingPort
				.getPreferredSize().height));

		lHostAddress = new JLabel("Host address: ");
		tfHostAddress = new JTextField();
		tfHostAddress.setText("127.0.0.1");
		lHostPort = new JLabel("Host port: ");
		sHostPort = new JSpinner();

		tfHostAddress.setPreferredSize(new Dimension(200, tfHostAddress
				.getPreferredSize().height));
		sHostPort.setPreferredSize(new Dimension(100, tfHostAddress
				.getPreferredSize().height));

		gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
		gbc.weightx = 0;
		gbc.weighty = 1;
		gbc.fill = GridBagConstraints.NONE;
		Insets normal = gbc.insets;
		Insets bottom = new Insets(15, normal.left, normal.bottom, normal.right);

		gbc.gridx = 0;
		gbc.gridy = 0;
		panel.add(lHostAddress, gbc);
		gbc.gridy = 1;
		panel.add(lHostPort, gbc);
		gbc.gridy = 2;
		gbc.insets = bottom;
		panel.add(lRingPort, gbc);

		gbc.anchor = GridBagConstraints.BASELINE_LEADING;
		gbc.weightx = 1;
		gbc.insets = normal;
		gbc.gridx = 1;
		gbc.gridy = 0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		panel.add(tfHostAddress, gbc);
		gbc.fill = GridBagConstraints.NONE;
		gbc.gridy = 1;
		panel.add(sHostPort, gbc);
		gbc.gridy = 2;
		gbc.insets = bottom;
		panel.add(sRingPort, gbc);

		return panel;
	}

	private JPanel createUserSettings() {
		JPanel panel = new JPanel();
		panel.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("User settings"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));
		panel.setLayout(new GridBagLayout());

		lUsername = new JLabel("Username: ");
		tfUsername = new JTextField();
		tfUsername.setPreferredSize(new Dimension(100, tfUsername
				.getPreferredSize().height));

		lMusicPath = new JLabel("Music folder: ");
		tfMusicPath = new JTextField();
		tfMusicPath.setPreferredSize(new Dimension(250, tfMusicPath
				.getPreferredSize().height));
		bBrowse = new JButton(new Browse("Browse ...", this));

		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
		gbc.weightx = 1;
		gbc.weighty = 1;

		gbc.fill = GridBagConstraints.NONE;
		gbc.gridx = 0;
		gbc.gridy = 0;
		panel.add(lUsername, gbc);

		gbc.gridwidth = 2;
		gbc.gridx = 1;
		gbc.anchor = GridBagConstraints.BASELINE_LEADING;
		panel.add(tfUsername, gbc);

		gbc.gridwidth = 1;
		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
		panel.add(lMusicPath, gbc);

		gbc.gridx = 1;
		gbc.weightx = 2;
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		panel.add(tfMusicPath, gbc);

		gbc.gridx = 2;
		gbc.weightx = 1;
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.BASELINE_LEADING;
		panel.add(bBrowse, gbc);

		return panel;
	}

	public String getMusicFolder() {
		return tfMusicPath.getText();
	}

	public void setMusicFolder(String path) {
		tfMusicPath.setText(path);
	}

	public String getHostAddress() {
		return tfHostAddress.getText();
	}

	public int getHostPort() {
		return (Integer) sHostPort.getValue();
	}

	public int getRingPort() {
		return (Integer) sRingPort.getValue();
	}

	public String getUsername() {
		return tfUsername.getText();
	}

	public void setState(String state) {
		status.setText(state);
		status.validate();
	}

	/**
	 * zeg tegen de luisteraar dat het volgende scherm geladen mag worden
	 */
	protected void nextWindow() {
		wfl.nextWindow(this);
	}

	private class FormListener implements DocumentListener, ChangeListener {
		@Override
		public void removeUpdate(DocumentEvent e) {
			checkConnect();
		}

		@Override
		public void insertUpdate(DocumentEvent e) {
			checkConnect();
		}

		@Override
		public void changedUpdate(DocumentEvent e) {
			checkConnect();
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			checkConnect();
		}

		/**
		 * controlleer of alle velden ingevuld zijn
		 */
		private void checkConnect() {
			// als alles ingevuld is, enable de connect knop.
			connect.setEnabled(tfHostAddress.getText().length() > 0
					&& (Integer) sHostPort.getValue() > 0
					&& (Integer) sRingPort.getValue() > 0
					&& tfUsername.getText().length() > 0);
		}
	}
}
